<?php
/*
 * Copyright (c) 2021.  Liuhongbin All rights reserved.
 * @domain http://dkyx.cc
 * @author liuhongbin <514660094@qq.com>
 */

namespace app\common\services;

use think\facade\Config;
use think\facade\Db;

class Upgrade
{
    public $prefix;

    public function __construct()
    {
        $this->prefix = Config::get('database.connections.mysql.prefix');
    }

    public function getVersion()
    {
        //更新目录
        $local_up_dir = app()->getRuntimePath() . "upgrade/";
        //临时目录
        $local = $this->get_file($local_up_dir . 'version');
        if (!$local) {
            $cloud = (new \app\common\model\system\Config())->getValueByKey('cloud');
            return ['version'=>$cloud['version'] ?? config('hiduoke.version')];
        }
        return json_decode($local, true);
    }

    /**
     * 获取文件内容
     * @param string $url 要获取的url
     * @return boolean res 成功返回内容 失败返回false
     */
   public function get_file($url)
    {
        if (trim($url) == '') {
            return false;
        }
        $opts = array(
            'http' => array(
                'method'  => "GET",
                'timeout' => 3,//单位秒
            )
        );
        $cnt = 0;
        while ($cnt < 3 && ($res = @file_get_contents($url, false, stream_context_create($opts))) === FALSE) $cnt++;
        if ($res === false) {
            return false;
        } else {
            return $res;
        }
    }

    /**
     * 遍历当前目录不包含下级目录
     * @param string $dir 要遍历的目录
     * @param string $file 要过滤的文件
     * @return array|false 包含所有文件及目录的数组
     */
    public function scan_dir($dir, $file = '')
    {
        if (trim($dir) == '') {
            return false;
        }
        $file_arr = scandir($dir);
        $new_arr = [];
        foreach ($file_arr as $item) {

            if ($item != ".." && $item != "." && $item != $file) {
                $new_arr[] = $item;
            }
        }
        return $new_arr;
    }

    /**
     * 遍历执行sql文件
     * @param string $dir
     * @return bool
     */
    public function carry_sql($dir = '')
    {
        if (trim($dir) == '') {
            return false;
        }
        $sql_file_res = $this->scan_dir($dir);
        if (!empty($sql_file_res)) {
            foreach ($sql_file_res as $k => $v) {
                if (!empty(strstr($v, '.sql'))) {
                    $lines = file($dir . $v);
                    $templine = '';
                    foreach ($lines as $line) {
                        if (substr($line, 0, 2) == '--' || $line == '' || substr($line, 0, 2) == '/*')
                            continue;
                        $templine .= $line;
                        if (substr(trim($line), -1, 1) == ';') {
                            $templine = str_ireplace('__PREFIX__', $this->prefix, $templine);
                            $templine = str_ireplace('INSERT INTO ', 'INSERT IGNORE INTO ', $templine);
                            try {
                                Db::execute($templine);
                            } catch (\Exception $e) {
                            }
                            $templine = '';
                        }
                    }
                }
            }
        } else {
            return true;
        }
        return true;
    }


    /**
     * 合并目录且只覆盖不一致的文件
     * @param $source string 要合并的文件夹
     * @param $target string 要合并的目的地
     * @return int 处理的文件数
     */
    public function copy_merge($source, $target)
    {
        if (trim($source) == '') {
            return false;
        }
        if (trim($target) == '') {
            return false;
        }
        // 路径处理
        $source = preg_replace('#/\\\\#', DIRECTORY_SEPARATOR, $source);
        $target = preg_replace('#\/#', DIRECTORY_SEPARATOR, $target);
        $source = rtrim($source, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
        $target = rtrim($target, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
        // 记录处理了多少文件
        $count = 0;
        // 如果目标目录不存在，则创建。
        if (!is_dir($target)) {
            mkdir($target, 0777, true);
            $count++;
        }
        // 搜索目录下的所有文件
        foreach (glob($source . '*') as $filename) {
            if (is_dir($filename)) {
                // 如果是目录，递归合并子目录下的文件。
                $count += $this->copy_merge($filename, $target . basename($filename));
            } elseif (is_file($filename)) {
                // 如果是文件，判断当前文件与目标文件是否一样，不一样则拷贝覆盖。
                // 这里使用的是文件md5进行的一致性判断，可靠但性能低。
                if (!file_exists($target . basename($filename)) || md5(file_get_contents($filename)) != md5(file_get_contents($target . basename($filename)))) {
                    copy($filename, $target . basename($filename));
                    $count++;
                }
            }
        }

        // 返回处理了多少个文件
        return $count;
    }


    /**
     * 遍历删除文件
     * @param $dir string 要删除的目录
     * @return bool 成功与否
     */
    public function deldir($dir)
    {
        if (trim($dir) == '') {
            return false;
        }
        //先删除目录下的文件：
        $dh = opendir($dir);
        while ($file = readdir($dh)) {
            if ($file != "." && $file != "..") {
                $fullpath = $dir . "/" . $file;
                if (!is_dir($fullpath)) {
                    unlink($fullpath);
                } else {
                    $this->deldir($fullpath);
                }
            }
        }

        closedir($dh);
        //删除当前文件夹：
        if (rmdir($dir)) {
            return true;
        } else {
            return false;
        }
    }
}
